#include "float.hpp"

using std::cin;
using std::cout;
typedef union {
    int i;
    float f;
} FL;

typedef union {
    long int i;
    double d;
} DL;

int main(int argc, char *argv[]) {
    /* double dStart, dEnd;
    cout << "start: ";
    cin >> dStart;
    cout << "end:   ";
    cin >> dEnd;
    half hStart(dStart), hEnd(dEnd);
    float result1 = HalfFunction::computeHalfToDoubleAllULP(hStart, hEnd);
    FL fl1, fl2, fl3;
    fl1.f = result1;
    fl2.i = fl1.i & 0xFFFF0000;
    fl3.i = fl1.i | 0x0000FFFF;
    float fstart = fl2.f, fend = fl3.f;
    double result2 = FloatFunction::computeFloatToDoubleAllULP(fstart, fend);
    DL dl1, dl2, dl3;
    dl1.d = result2;
    dl2.i = (dl1.i - 1) & 0xFFFFFFFFF0000000;
    dl3.i = dl1.i | 0x000000000FFFFFFF;
    long int samplePointNumber = 0;
    cout << "Double均匀采样点个数: ";
    cin >> samplePointNumber;
    DoubleFunction::computeAllRandomULP(dl2.d, dl3.d, samplePointNumber);
    DoubleFunction::computeAllRandomULP(dStart, dEnd, samplePointNumber);
    //穷举[a,b]内所有double点，时间开销很大
    // cout << "穷举" << abs(dl2.i - dl3.i) << "个double点" << endl;
    // DoubleFunction::computeAllULP(dl2.d, dl3.d);
    cout << "从float类型开始穷举" << endl;
    float float_start = (float)dStart, float_end = (float)dEnd;
    double result3 = FloatFunction::computeFloatToDoubleAllULP(float_start, float_end);
    DL dl11, dl22, dl33;
    dl11.d = result3;
    dl22.d = result3;
    dl22.i = (dl11.i - 1) & 0xFFFFFFFFF0000000;
    dl33.i = dl11.i | 0x000000000FFFFFFF;
    long int samplePointNumber1 = 0;
    cout << "Double均匀采样点个数: ";
    cin >> samplePointNumber1;
    DoubleFunction::computeAllRandomULP(dl22.d, dl33.d, samplePointNumber1); */

    //操作double尾数位检测代码
    // double start, end;
    // cout << "start: ";
    // cin >> start;
    // cout << "end: ";
    // cin >> end;
    double start = 0.0, end = 0.0;
    if (argc != 3) {
        cout << "please input two number" << endl;
    } else {
        start = atof(argv[1]);
        end = atof(argv[2]);
    }
    if (start > end) {
        cout << "start > end, input range error, you have to input start <= end" << endl;
        return 0;
    } else if (end <= 0) {//处理start和end<=0的情况
        DoubleFunction::detectMethod2_1(start, end);
    } else if (start < 0 && end > 0) {//处理start<0但是end>0的情况，即区间跨越了0
        DoubleFunction::detectMethod2_2(start, end);
    } else {//处理start和end都大于等于0的情况
        DoubleFunction::detectMethod2(start, end); 
    }
    /* cout << "均匀采样10w点结果: " << endl;
    DoubleFunction::computeAllRandomULP(start, end, 100000); */
    /* cout << "模拟退火算法:";
    vector<double> vec = DoubleFunction::simulated_annealing(start, end);
    for (auto x : vec) cout << x << endl; */
    return 0;
}
